﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using NASA.BeAMartian.Controls;
using NASA.BeAMartian.Model;
using NASA.BeAMartian.Controls.Primitives;
using System.Windows.Controls.Primitives;
using System.Windows.Media.Imaging;
using GalaxyZoo.Client.Model;

namespace NASA.BeAMartian.Controls
{
    public partial class CraterSelector : UserControl
    {
        public event EventHandler CraterCountChanged;

        /// <summary>
        /// The task.
        /// </summary>
        private CraterTask craterTask = null;

        // compensation for distance from the outter border of 
        // initial mouse click that initiated the resize.
        private double distRadiusDelta = -1;

        public CraterSelector()
        {
            InitializeComponent();

            this.MouseLeftButtonDown += new MouseButtonEventHandler(CraterSelector_MouseLeftButtonDown);
        }

        public void Populate(CraterTask craterTask)
        {
            this.craterTask = craterTask;

            this.ImageStack.Children.Clear();

            int totalWidth = 0;
            int totalHeight = 0;

            foreach (BitmapSource source in craterTask.BackgroundImages)
            {
                if (source == null)
                    continue;

                Image image = new Image()
                {
                    Source = source,
                    Stretch = Stretch.None,
                    Width = source.PixelWidth,
                    Height = source.PixelHeight,
                    //Margin = new Thickness(1,0,0,0)
                };

                if (source.PixelHeight > totalHeight)
                    totalHeight = source.PixelHeight;

                totalWidth += source.PixelWidth;

                this.ImageStack.Children.Add(image);
            }

            this.MainContainer.Width = totalWidth;
            this.MainContainer.Height = totalHeight;
        }

        public int CountedCraters
        {
            get { return this.MainCanvas.Children.Count; }
        }

        public double SelectorOpacity
        {
            set { this.MainCanvas.Opacity = value; }
            get { return this.MainCanvas.Opacity; }
        }

        public CraterTask GetCraterTask()
        {
            if (this.craterTask != null)
            {
                if (this.craterTask.CraterDefinitions == null)
                    this.craterTask.CraterDefinitions = new List<CircularCraterDefinition>();
                else
                    this.craterTask.CraterDefinitions.Clear();

                foreach (ResizableThumb thumb in this.MainCanvas.Children)
                {
                    this.craterTask.CraterDefinitions.Add(
                    new CircularCraterDefinition()
                    {
                        OffsetCenterX = Canvas.GetLeft(thumb) + thumb.Width / 2.0,
                        OffsetCenterY = Canvas.GetTop(thumb) + thumb.Height / 2.0,
                        Diameter = thumb.Width - 15
                    });
                }
            }

            return this.craterTask;
        }

        public bool IsProcessing
        {
            set
            {
                if (value)
                {
                    this.ProcessingIndicator.Opacity = 1.0;
                    this.ProcessingIndicator.Start();
                }
                else
                {
                    this.ProcessingIndicator.Opacity = 0.0;
                    this.ProcessingIndicator.Stop();
                }
            }
        }

        protected void OnCraterCountChanged()
        {
            if (this.CraterCountChanged != null)
                this.CraterCountChanged(this, EventArgs.Empty);
        }

        private void SelectorThumbOne_ResizeStarted(object sender, ResizeStartedEventArgs e)
        {
            ResizableThumb thumb = sender as ResizableThumb;

            // bring the thumb to the front.
            foreach (ResizableThumb childThumb in this.MainCanvas.Children)
                Canvas.SetZIndex(childThumb, (thumb == childThumb ? 1 : 0));

            if (thumb != null)
            {
                double dist = Math.Sqrt((e.HorizontalDistance * e.HorizontalDistance) + (e.VerticalDistance * e.VerticalDistance));
                distRadiusDelta = (thumb.Width / 2.0) - dist;
            }
        }

        private void SelectorThumbOne_ResizeDelta(object sender, ResizeEventArgs e)
        {
            ResizableThumb thumb = sender as ResizableThumb;

            if (thumb != null)
            {
                double dist = Math.Sqrt((e.HorizontalDistance * e.HorizontalDistance) + (e.VerticalDistance * e.VerticalDistance));
                dist = (dist + distRadiusDelta) * 2.0;

                if (dist < thumb.MinHeight) dist = thumb.MinHeight;

                Canvas.SetTop(thumb, Canvas.GetTop(thumb) + (thumb.Height - dist) / 2.0);
                Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + (thumb.Width - dist) / 2.0);

                thumb.Width = dist;
                thumb.Height = dist;
            }
        }

        private void SelectorThumbOne_ResizeCompleted(object sender, ResizeCompletedEventArgs e)
        {
            // noop
        }

        private void SelectorThumbOne_DragStarted(object sender, DragStartedEventArgs e)
        {
            ResizableThumb thumb = sender as ResizableThumb;
            // bring the thumb to the front.
            foreach (ResizableThumb childThumb in this.MainCanvas.Children)
                Canvas.SetZIndex(childThumb, (thumb == childThumb ? 1 : 0));
        }

        private void SelectorThumbOne_DragDelta(object sender, DragDeltaEventArgs e)
        {
            ResizableThumb thumb = sender as ResizableThumb;

            if (thumb != null)
            {
                Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange);
                Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange);
            }
        }

        private void SelectorThumbOne_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            // noop
        }

        private void AddCraterSelectorControl(System.Windows.Point position)
        {
            ResizableThumb thumb = new ResizableThumb();
            thumb.Style = this.Resources["ResizableThumbOneStyle"] as Style;
            thumb.Width = 40;
            thumb.Height = 40;
            thumb.DataContext = thumb;
            thumb.UseLayoutRounding = false;

            this.MainCanvas.Children.Add(thumb);

            Canvas.SetLeft(thumb, position.X - (thumb.Width / 2.0));
            Canvas.SetTop(thumb, position.Y - (thumb.Height / 2.0));

            thumb.ResizeStarted += new EventHandler<ResizeStartedEventArgs>(SelectorThumbOne_ResizeStarted);
            thumb.ResizeDelta += new EventHandler<ResizeEventArgs>(SelectorThumbOne_ResizeDelta);
            thumb.ResizeCompleted += new EventHandler<ResizeCompletedEventArgs>(SelectorThumbOne_ResizeCompleted);
            thumb.DragStarted += new EventHandler<DragStartedEventArgs>(SelectorThumbOne_DragStarted);
            thumb.DragDelta += new EventHandler<DragDeltaEventArgs>(SelectorThumbOne_DragDelta);
            thumb.DragCompleted += new EventHandler<DragCompletedEventArgs>(SelectorThumbOne_DragCompleted);

            thumb.Focus();

            this.OnCraterCountChanged();
        }

        private void RemoveCraterSelectorControl(ResizableThumb thumb)
        {
            thumb.ResizeStarted -= new EventHandler<ResizeStartedEventArgs>(SelectorThumbOne_ResizeStarted);
            thumb.ResizeDelta -= new EventHandler<ResizeEventArgs>(SelectorThumbOne_ResizeDelta);
            thumb.ResizeCompleted -= new EventHandler<ResizeCompletedEventArgs>(SelectorThumbOne_ResizeCompleted);
            thumb.DragStarted -= new EventHandler<DragStartedEventArgs>(SelectorThumbOne_DragStarted);
            thumb.DragDelta -= new EventHandler<DragDeltaEventArgs>(SelectorThumbOne_DragDelta);
            thumb.DragCompleted -= new EventHandler<DragCompletedEventArgs>(SelectorThumbOne_DragCompleted);

            this.MainCanvas.Children.Remove(thumb);

            this.OnCraterCountChanged();
        }

        private void CraterSelector_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.AddCraterSelectorControl(e.GetPosition(this.MainCanvas));
        }

        private void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            Button button = (Button)sender;
            this.RemoveCraterSelectorControl(button.Tag as ResizableThumb);
        }
    }
}
